#!/usr/bin/env python

#server
import socket
import threading
import time
import pkgutil
import types

try:
    from core.ide.datamangager import DataMangager
except:
    pass
SIZE = 4

try:
    HOST=DataMangager().getData("Druid","Socket Server","127.0.0.1",None,"Socket")
    PORT=DataMangager().getData("Druid","Socket Port",5432,None,"Socket")
except:
    HOST="127.0.0.1"
    PORT=5432
    
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind((HOST,PORT))
soc.listen(5)

class CThread(threading.Thread):
    def __init__(self,server,client):
        threading.Thread.__init__(self)
        self.server = server
        self.client=client
        self.stopIt=False

    def getMessageRecv(self):
        data = self.server.recv(SIZE)
        self.server.send('OK')
        msg = self.server.recv(int(data))
        return msg

    def run(self):
        while not self.stopIt:
            msg = self.getMessageRecv()
            if msg[0]=="$":
                s=msg[1:].split(" ")
                m=getattr(self,"read_"+s[0])(s)
                if not m:
                    return
                msend(self.client,str(m))
            msend(self.client,'__$end__')

    def read_infos(self,arg):
        name=arg[1]
        module=None

        if len(arg)>2:
            module=arg[2]
            
        infos={}
        infos["name"]=name
        infos["module"]=module
        
        if module:
            try:
                modules=module.split(".")
                m=__import__(modules[0])
                modules=modules[1:]
                for subm in modules:
                    m=getattr(m,subm)
                r=getattr(m,name)
            except:
                return '__$none__'
        else:
            r=eval(name)
        infos["type"]=type(r)
        infos["list"]=dir(r)
        infos["doc"]=r.__doc__
        if type(r)==types.FunctionType:
            infos["param"]=r.__code__.co_varnames
        if type(r)==types.MethodType:
            infos["param"]=r.im_func.func_code.co_varnames
        if infos.has_key("param"):
            p=[]
            for i in range(len( infos["param"])):
                param=infos["param"][i]
                if param:
                    p.append(param)
            infos["param"]=p
            
        return infos

    def read_modules(self,arg):
        infos={}
        
        if len(arg)<2:
            infos["list"]=[]
            for importer, modname, ispkg in pkgutil.iter_modules():
                infos["list"].append(modname)
        else:
            infos["module"]=arg[1]
            module=arg[1]
            try:
                modules=module.split(".")
                m=__import__(modules[0])
                modules=modules[1:]
                for subm in modules:
                    m=getattr(m,subm)
            except:
                return '__$none__'
            infos["list"]=dir(m)    
        return infos
    
    def read_close(self,arg):
        global soc
        self.server.close()
        self.client.close()
        soc.close()
        return None

def setConn(con1,con2):
    dict={}
    state = con1.recv(5)
    con2.recv(5)
    if state =='$RECV':
        dict['send'] = con1 # server will send data to reciever
        dict['recv'] = con2
    else:
        dict['recv'] = con1 # server will recieve data from sender
        dict['send'] = con2
    return dict

def msend(conn,msg):
    if len(msg)<=999 and len(msg)>0:
        conn.send(str(len(msg)))
        if conn.recv(2) == 'OK':
            conn.send(msg)
    else:
        conn.send(str(999))
        if conn.recv(2) == 'OK':
            conn.send(msg[:999])
            msend(conn,msg[1000:]) # calling recursive


(server,a1) = soc.accept()
(client,a2) = soc.accept()
dict = setConn(server,client)
thr = CThread(server,client)
thr.start()
#try:
#    while 1:
#        msend(dict['send'],raw_input())
#except:
#    print 'closing'
#thr.stopIt=True
#msend(dict['send'],'bye!!!')# for stoping the thread
#thr.conn.close()
#soc.close()